﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Algobox.JuicyLib.SQL.LiquidView;
using Algobox.JuicyLib.IO.CSV;
using System.IO;

namespace LiquidTrading.LiquidViewSyncTool
{
    public class ProcessTrqx
    {

        const char SEPERATOR_ROW = '\n';
        const char SEPERATOR_COL = ',';

        const int SYMBOL_NUM_COL = 14;

        const int SYMBOL_PRI_NAME = 0;
        const int SYMBOL_PRI_MIC = 1;
        const int SYMBOL_PRI_ISIN = 3;
        const int SYMBOL_PRI_UMTF = 4;

        const int SYMBOL_LOC_CCY = 5;
        const int SYMBOL_LOC_TICK = 10;

        const int TICK_NUM_COL = 4;

        const int TICK_NAME = 0;
        const int TICK_MIN = 2;
        const int TICK_SIZE = 3;

        public static bool ProcessTicks(LiquidViewLinqDataContext linq, byte[] buffer)
        {

            Dictionary<decimal, decimal> pair;
            Dictionary<string, Dictionary<decimal, decimal>> ranges = new Dictionary<string, Dictionary<decimal, decimal>>();

            using (CsvReader csv = new CsvReader(new StreamReader(new MemoryStream(buffer, false)), true, SEPERATOR_COL, '"', '\0', '#', true))
            {
                string tickName;
                decimal min;
                decimal size;

                csv.DefaultParseErrorAction = ParseErrorAction.AdvanceToNextLine;
                while (csv.ReadNextRecord())
                {
                    tickName = csv[TICK_NAME];

                    if (!Decimal.TryParse(csv[TICK_MIN], out min))
                        linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Turquoise Ticks - Couldn't decode TICK_MIN " + csv[TICK_MIN], null);

                    if (!Decimal.TryParse(csv[TICK_SIZE], out size))
                        linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Turquoise Ticks - Couldn't decode TICK_SIZE " + csv[TICK_SIZE], null);

                    if (!ranges.TryGetValue(tickName, out pair))
                    {
                        pair = new Dictionary<decimal, decimal>();
                        ranges.Add(tickName, pair);
                    }
                    ranges[tickName].Add(min, size);
                }
            }

            long? tickSizeId = null;

            // insert non dynamic - or fixed - tick sizes
            foreach (string tickName in ranges.Where(a => a.Value.Count == 1).Select(a => a.Key))
            {
                KeyValuePair<decimal, decimal> range = ranges[tickName].First();

                int result = linq.ImportTickSize(tickName, "TRQX", null, range.Value, ref tickSizeId);

                if (result != 4)
                {
                    if (result == 0)
                    {
                        Console.WriteLine("Created " + tickName);
                        linq.ExceptionHandlerThrow("LiquidViewSyncTool", "New Turquoise fixed Tick Range " + tickName + " created", null);
                    }
                    else if (result == 2)
                    {
                        linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Changed Turquoise Tick Range type from dynamic to fixed for " + tickName, null);
                    }
                    else if (result == 3)
                    {
                        linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Changed Turquoise fixed Tick Range to " + range.Value + " for " + tickName, null);
                    }
                    else if (result == -1)
                    {
                        string message = "General failure processing " + tickName;
                        linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Turquoise fixed Tick Range - " + message, null);
                    }
                    else if (result == -2)
                    {
                        string message = "ExchangeMIC failure processing " + tickName + " with fixed value of " + range.Value;
                        linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Turquoise fixed Tick Range - " + message, null);
                    }
                    else
                    {
                        linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Turquoise fixed Tick Range - Unknown return value on ImportTickSize", null);
                    }
                }
            }


            //insert dynamic tick sizes
            foreach (string tickName in ranges.Where(a => a.Value.Count > 1).Select(a => a.Key))
            {
                foreach (KeyValuePair<decimal, decimal> range in ranges[tickName])
                {
                    int result = linq.ImportTickSize(tickName, "TRQX", range.Key, range.Value, ref tickSizeId);

                    if (result != 4)
                    {
                        if (result == 0)
                        {
                            Console.WriteLine("Created " + tickName);
                            linq.ExceptionHandlerThrow("LiquidViewSyncTool", "New Turquoise dynamic Tick Range " + tickName + " created", null);
                        }
                        else if (result == 1)
                        {
                            linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Added new Turquoise dynamic Tick Range to " + tickName + " " + range.Key + ":" + range.Value, null);
                        }
                        else if (result == 2)
                        {
                            linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Changed Turquoise Tick Range type from fixed to dynamic for " + tickName, null);
                        }
                        else if (result == -1)
                        {
                            string message = "General failure processing " + tickName;
                            linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Turquoise dynamic Tick Range - " + message, null);
                        }
                        else if (result == -2)
                        {
                            string message = "ExchangeMIC failure processing " + tickName + " with fixed value of " + range.Value;
                            linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Turquoise dynamic Tick Range - " + message, null);
                        }
                        else
                        {
                            linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Turquoise dynamic Tick Range - Unknown return value on ImportTickSize", null);
                        }
                    }
                }
            }

            return true;
        }



        //public static bool ProcessSymbols(LiquidViewLinqDataContext linq, ref string symbols)
        public static bool ProcessSymbols(LiquidViewLinqDataContext linq, byte[] buffer)
        {
            string currency;

            using (CsvReader csv = new CsvReader(new StreamReader(new MemoryStream(buffer, false)), true, SEPERATOR_COL, '"', '\0', '#', true))
            {
                csv.DefaultParseErrorAction = ParseErrorAction.AdvanceToNextLine;
                while (csv.ReadNextRecord())
                {
                    // update InstrumentStock               
                    currency = csv[SYMBOL_LOC_CCY];
                    if (currency == "GBp" || currency == "GBX")
                        currency = "GBP";

                    string market = Program.CompareTheMeerkat(csv[SYMBOL_PRI_MIC]);

                    int? stockId = null;

                    // inport instrument stock
                    /*
                    int result = linq.ImportInstrumentStock(
                        csv[SYMBOL_PRI_MIC],
                        currency,
                        csv[SYMBOL_PRI_ISIN],
                        null,
                        csv[SYMBOL_PRI_UMTF],
                        csv[SYMBOL_PRI_UMTF],
                        csv[SYMBOL_PRI_NAME],
                        null,
                        null,
                        null,
                        null,
                        null,
                        false,
                        ref stockId);
                     * */
                    int result = linq.ImportInstrumentStockByUMTF(
                        csv[SYMBOL_PRI_UMTF],
                        market,
                        currency,
                        csv[SYMBOL_PRI_ISIN],
                        null,
                        csv[SYMBOL_PRI_NAME],
                        null,
                        null,
                        null,
                        null,
                        null,
                        false,
                        ref stockId);



                    if (result == 0)
                    {
                        Console.WriteLine("Created " + csv[SYMBOL_PRI_UMTF]);
                        linq.ExceptionHandlerThrow("LiquidViewSyncTool", "New Turquoise stock " + csv[SYMBOL_PRI_UMTF] + " created", null);
                    }
                    else if (result == 1)
                    {
                        //Console.WriteLine("Updated...");
                    }
                    else if (result == 2)
                    {
                        Console.WriteLine("Changed MarketMIC for " + csv[SYMBOL_PRI_UMTF]);
                        linq.ExceptionHandlerThrow("LiquidViewSyncTool", "WARNING: Market changed for " + csv[SYMBOL_PRI_UMTF], null);
                    }
                    else if (result == 3)
                    {
                        Console.WriteLine("Changed Currency for " + csv[SYMBOL_PRI_UMTF]);
                        linq.ExceptionHandlerThrow("LiquidViewSyncTool", "WARNING: Currency changed for " + csv[SYMBOL_PRI_UMTF], null);
                    }
                    else if (result == 4)
                    {
                        Console.WriteLine("Created " + csv[SYMBOL_PRI_UMTF]);
                        linq.ExceptionHandlerThrow("LiquidViewSyncTool", "WARNING: Market and Currency changed for " + csv[SYMBOL_PRI_UMTF], null);
                    }
                    else if (result < 0)
                    {
                        if (result == -1)
                        {
                            string message = "General failure processing " + csv[SYMBOL_PRI_UMTF];
                            linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Turquoise Symbols - " + message, null);
                        }
                        else if (result == -2)
                        {
                            string message = "MarketMIC failure processing " + csv[SYMBOL_PRI_UMTF] + " with " + market;
                            linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Turquoise Symbols - " + message, null);
                        }
                        else if (result == -3)
                        {
                            string message = "Currency failure processing " + csv[SYMBOL_PRI_UMTF] + " with " + currency;
                            linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Turquoise Symbols - " + message, null);
                        }
                        else
                        {
                            string message = "Some other failure processing failure processing " + csv[SYMBOL_PRI_UMTF];
                            linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Turquoise Symbols - " + message, null);
                        }
                    }
                    else
                    {
                        linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Turquoise Symbols - Unknown return value on ImportInstrumentStock", null);
                    }


                    int? listingId = null;

                    currency = csv[SYMBOL_LOC_CCY];
                    if (currency == "GBp")
                        currency = "GBX";

                    // inport instrument stock listing
                    result = linq.ImportInstrumentStockListing(
                        stockId,
                        "TRQX",
                        currency,
                        csv[SYMBOL_LOC_TICK],
                        csv[SYMBOL_PRI_UMTF],
                        null,
                        null,
                        ref listingId);

                    if (result == 0)
                    {
                        Console.WriteLine("Created Stock Listing for " + csv[SYMBOL_PRI_UMTF]);
                        linq.ExceptionHandlerThrow("LiquidViewSyncTool", "New Turquoise Stock Listing " + csv[SYMBOL_PRI_UMTF] + " created", null);
                    }
                    else if (result == 1)
                    {
                        //Console.WriteLine("Updated...");
                    }
                    else if (result == -1)
                    {
                        string message = "General failure processing " + csv[SYMBOL_PRI_UMTF];
                        linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Turquoise Stock Listing - " + message, null);
                    }
                    else if (result == -2)
                    {
                        string message = "ExchangMIC failure processing CHIX";
                        linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Turquoise Stock Listing - " + message, null);
                    }
                    else if (result == -3)
                    {
                        string message = "StockId failure processing " + stockId;
                        linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Turquoise Stock Listing - " + message, null);
                    }
                    else if (result == -4)
                    {
                        string message = "Tick range failure processing " + csv[SYMBOL_PRI_UMTF] + " with " + csv[SYMBOL_LOC_TICK];
                        linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Turquoise Stock Listing - " + message, null);

                    }
                    else
                    {
                        linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Turquoise Stock Listing - Unknown return value on ImportInstrumentStock", null);
                    }
                }
            }
            return true;

        }

    }
}
